package com.xujie.property_warranty_system.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xujie.property_warranty_system.dto.FacilityDTO;
import com.xujie.property_warranty_system.dto.FacilityQueryDTO;
import com.xujie.property_warranty_system.dto.FacilityVO;
import com.xujie.property_warranty_system.dto.PageResult;
import com.xujie.property_warranty_system.entity.Facility;
import com.xujie.property_warranty_system.enums.FacilityStatus;
import com.xujie.property_warranty_system.mapper.FacilityMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 设施设备服务类
 */
@Service
public class FacilityService extends ServiceImpl<FacilityMapper, Facility> {
    
    @Autowired
    private FacilityMapper facilityMapper;
    
    /**
     * 分页查询设施设备
     */
    public PageResult<FacilityVO> getFacilityPage(FacilityQueryDTO queryDTO) {
        // 创建分页对象
        Page<Facility> page = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        
        // 构建查询条件
        QueryWrapper<Facility> queryWrapper = new QueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                .like("facility_code", queryDTO.getKeyword())
                .or().like("facility_name", queryDTO.getKeyword())
                .or().like("location", queryDTO.getKeyword())
            );
        }
        
        // 状态筛选
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }
        
        // 设备类型筛选
        if (StringUtils.hasText(queryDTO.getFacilityType())) {
            queryWrapper.eq("facility_type", queryDTO.getFacilityType());
        }
        
        // 即将到期维护筛选
        if (Boolean.TRUE.equals(queryDTO.getMaintenanceSoon())) {
            LocalDate thirtyDaysLater = LocalDate.now().plusDays(30);
            queryWrapper.isNotNull("next_maintenance_date")
                .le("next_maintenance_date", thirtyDaysLater);
        }
        
        // 按创建时间倒序
        queryWrapper.orderByDesc("create_time");
        
        // 执行分页查询
        Page<Facility> facilityPage = facilityMapper.selectPage(page, queryWrapper);
        
        // 转换为VO对象
        List<FacilityVO> facilityVOList = facilityPage.getRecords().stream().map(this::convertToVO).collect(Collectors.toList());
        
        return new PageResult<>(
            facilityVOList,
            facilityPage.getTotal(),
            (int) facilityPage.getCurrent(),
            (int) facilityPage.getSize()
        );
    }
    
    /**
     * 获取设施设备详情
     */
    public FacilityVO getFacilityDetail(Long id) {
        Facility facility = facilityMapper.selectById(id);
        if (facility == null) {
            throw new RuntimeException("设备不存在");
        }
        
        return convertToVO(facility);
    }
    
    /**
     * 添加设施设备
     */
    @Transactional
    public Long addFacility(FacilityDTO facilityDTO) {
        // 检查设备编号是否已存在
        QueryWrapper<Facility> codeQuery = new QueryWrapper<>();
        codeQuery.eq("facility_code", facilityDTO.getFacilityCode());
        if (facilityMapper.selectOne(codeQuery) != null) {
            throw new RuntimeException("设备编号已存在");
        }
        
        // 创建设备对象
        Facility facility = new Facility();
        BeanUtils.copyProperties(facilityDTO, facility);
        
        // 如果设置了上次维护日期和维护周期，自动计算下次维护日期
        if (facility.getLastMaintenanceDate() != null && facility.getMaintenanceCycle() != null) {
            facility.setNextMaintenanceDate(facility.getLastMaintenanceDate().plusDays(facility.getMaintenanceCycle()));
        }
        
        // 保存设备
        facilityMapper.insert(facility);
        
        return facility.getId();
    }
    
    /**
     * 更新设施设备
     */
    @Transactional
    public void updateFacility(FacilityDTO facilityDTO) {
        if (facilityDTO.getId() == null) {
            throw new RuntimeException("设备ID不能为空");
        }
        
        // 检查设备是否存在
        Facility existingFacility = facilityMapper.selectById(facilityDTO.getId());
        if (existingFacility == null) {
            throw new RuntimeException("设备不存在");
        }
        
        // 检查设备编号是否已被其他设备使用
        if (!existingFacility.getFacilityCode().equals(facilityDTO.getFacilityCode())) {
            QueryWrapper<Facility> codeQuery = new QueryWrapper<>();
            codeQuery.eq("facility_code", facilityDTO.getFacilityCode());
            codeQuery.ne("id", facilityDTO.getId());
            if (facilityMapper.selectOne(codeQuery) != null) {
                throw new RuntimeException("设备编号已被其他设备使用");
            }
        }
        
        // 更新设备信息
        Facility facility = new Facility();
        BeanUtils.copyProperties(facilityDTO, facility);
        
        // 如果设置了上次维护日期和维护周期，自动计算下次维护日期
        if (facility.getLastMaintenanceDate() != null && facility.getMaintenanceCycle() != null) {
            facility.setNextMaintenanceDate(facility.getLastMaintenanceDate().plusDays(facility.getMaintenanceCycle()));
        }
        
        facilityMapper.updateById(facility);
    }
    
    /**
     * 删除设施设备
     */
    @Transactional
    public void deleteFacility(Long id) {
        // 检查设备是否存在
        Facility facility = facilityMapper.selectById(id);
        if (facility == null) {
            throw new RuntimeException("设备不存在");
        }
        
        // 删除设备
        facilityMapper.deleteById(id);
    }
    
    /**
     * 获取所有设备类型
     */
    public List<String> getAllFacilityTypes() {
        QueryWrapper<Facility> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("DISTINCT facility_type");
        queryWrapper.isNotNull("facility_type");
        
        return facilityMapper.selectList(queryWrapper)
            .stream()
            .map(Facility::getFacilityType)
            .filter(StringUtils::hasText)
            .collect(Collectors.toList());
    }
    
    /**
     * 获取设备统计信息
     */
    public FacilityStatisticsVO getStatistics() {
        FacilityStatisticsVO statistics = new FacilityStatisticsVO();
        
        // 总设备数
        statistics.setTotalCount(facilityMapper.selectCount(null));
        
        // 正常设备数
        QueryWrapper<Facility> normalQuery = new QueryWrapper<>();
        normalQuery.eq("status", FacilityStatus.NORMAL.getCode());
        statistics.setNormalCount(facilityMapper.selectCount(normalQuery));
        
        // 维修中设备数
        QueryWrapper<Facility> maintainingQuery = new QueryWrapper<>();
        maintainingQuery.eq("status", FacilityStatus.MAINTAINING.getCode());
        statistics.setMaintainingCount(facilityMapper.selectCount(maintainingQuery));
        
        // 报废设备数
        QueryWrapper<Facility> scrappedQuery = new QueryWrapper<>();
        scrappedQuery.eq("status", FacilityStatus.SCRAPPED.getCode());
        statistics.setScrappedCount(facilityMapper.selectCount(scrappedQuery));
        
        // 即将到期维护设备数
        QueryWrapper<Facility> maintenanceSoonQuery = new QueryWrapper<>();
        maintenanceSoonQuery.isNotNull("next_maintenance_date");
        maintenanceSoonQuery.le("next_maintenance_date", LocalDate.now().plusDays(30));
        statistics.setMaintenanceSoonCount(facilityMapper.selectCount(maintenanceSoonQuery));
        
        return statistics;
    }
    
    /**
     * 将实体转换为VO
     */
    private FacilityVO convertToVO(Facility facility) {
        FacilityVO facilityVO = new FacilityVO();
        BeanUtils.copyProperties(facility, facilityVO);
        
        // 设置状态描述
        facilityVO.setStatusDesc(FacilityStatus.fromCode(facility.getStatus()).getDescription());
        
        // 计算距离下次维护天数
        if (facility.getNextMaintenanceDate() != null) {
            long daysToNextMaintenance = ChronoUnit.DAYS.between(LocalDate.now(), facility.getNextMaintenanceDate());
            facilityVO.setDaysToNextMaintenance((int) daysToNextMaintenance);
        }
        
        // 判断是否在保修期内
        if (facility.getPurchaseDate() != null && facility.getWarrantyPeriod() != null) {
            LocalDate warrantyEndDate = facility.getPurchaseDate().plusMonths(facility.getWarrantyPeriod());
            facilityVO.setInWarranty(LocalDate.now().isBefore(warrantyEndDate) || LocalDate.now().isEqual(warrantyEndDate));
        } else {
            facilityVO.setInWarranty(false);
        }
        
        return facilityVO;
    }
    
    /**
     * 设备统计信息VO
     */
    @lombok.Data
    public static class FacilityStatisticsVO {
        private Long totalCount = 0L;
        private Long normalCount = 0L;
        private Long maintainingCount = 0L;
        private Long scrappedCount = 0L;
        private Long maintenanceSoonCount = 0L;
    }
}
